/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
 * Microsystems, Inc. All Rights Reserved.
 */


package org.medbeans.modules.search.types;


import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.openide.loaders.DataObject;
import org.openide.TopManager;
import org.openide.util.HelpCtx;


/**
 * Test DataObject loader match.
 *
 * @author  Petr Kuzel
 */
public class ObjectTypeType extends DataObjectType {

    /** Serial version UID. */
    static final long serialVersionUID = 1L;

    /** stream replacing. */
    private final static String NAMES_FIELD = "classNames";
    
    /** Serial persistent fields. */
    private static final ObjectStreamField[] serialPersistentFields
                         = {new ObjectStreamField(NAMES_FIELD, List.class)};

    /** Which classes to serch. */
    private transient Class[] mask = new Class[0];
                         

    /** Test whether this data object meets criteria. */
    public boolean testDataObject(DataObject dataObject) {
        Class ld = dataObject.getLoader().getClass();

        for (int i=0; i<mask.length; i++) {
            if (mask[i].isAssignableFrom(ld)) 
                return true;
        }

        return false;
    }

    /** Setter for mask property. */
    public void setMask(Class[] mask) {
        Class[] old = this.mask;
        this.mask = mask;
        firePropertyChange("mask", null, null); // NOI18N
        setValid(true);
    }

    /** Getter for mask property. */
    public Class[] getMask() {
        return mask;
    }
    
    /** Setter for mask property. */
    public void setMask(int i, Class m) {
        mask[i] = m;
        firePropertyChange("mask", null, null);  // NOI18N
        setValid(true);
    }
    
    /** Getter for mask property. */
    public Class getMask(int i) {
        return mask[i];
    }

    /** Gets help context for this search type.
     * Implements superclass abstract method. */
    public HelpCtx getHelpCtx() {
        return new HelpCtx(ObjectTypeType.class);
    }
    
    /** Store itself as sequence of class names. */
    private void writeObject(ObjectOutputStream out) throws IOException {
        List classNames = new ArrayList(mask == null ? 0 : mask.length);
        
        if(mask != null) {
            for(int i = 0; i<mask.length; i++) {
                if(mask[i] == null) {
                    continue;
                }
                
                classNames.add(mask[i].getName());
            }
        }
        
        out.putFields().put(NAMES_FIELD, classNames);
        out.writeFields();
    }

    /** Restore itself from sequence of class names. */
    private void readObject(ObjectInputStream in)
    throws IOException, ClassNotFoundException {
        List classNames = (List)in.readFields().get(NAMES_FIELD, new ArrayList());

        // fill mask array
        List classes = new ArrayList(classNames.size());
        
        Iterator it = classNames.iterator();
        while(it.hasNext()) {
            try {
                classes.add(Class.forName((String)it.next(), false, TopManager.getDefault().currentClassLoader()));
            } catch (ClassNotFoundException cnfe) {
                cnfe.printStackTrace();
            }
        }
        
        mask = new Class[classes.size()];
        classes.toArray(mask);

        setValid(false);
    }
    
}
